import itertools
import numpy as np
import pandas as pd
from core.LiuYao import LiuYaoPlace
from core.engine.DictTensor import DictTensor
from core.engine.HexMatxOperator import HexagramMatrixOperator
from constants import ZHI_TO_WX, GAN, ZHI, GUA_NAME, REMINDER_TO_WX, REMAINDER_TO_SIX_MODE, \
     LIU_QIN_NUM_60, YAO_WEI, ANIMALS
from utils.attr_dict import AttrFuncDict
from utils.for_np import *
from test_cases import gua_dicts

WX = ['金', '水', '木', '火', '土']
WXDiff = ['扶', '生', '克', '耗', '泄']
LQin = ['兄弟', '子孙', '妻财', '官鬼', '父母']
LYao = ['六', '五', '四', '三', '二', '初']
YShen = ['用神', '闲神', '仇神', '忌神', '元神']
gua_dict = gua_dicts[3]

clauses = [
    [i + '爻' for i in YAO_WEI],  # 0
    ['安静', '发动', '外卦', '内卦', '主卦', '变卦', '伏藏', '暗动'],
    [i for i in '阴阳'],
    ['金', '水', '木', '火', '土'],  # 3
    ZHI + ['空亡'],
    ANIMALS,
    LQin + ["世爻", "应爻", "间爻"],  # 6
    ["世", "应", "间", '动'],
    [prefix + diff for prefix in ['月', '日'] for diff in WXDiff],
    [prefix + _ + str(i) for prefix in ['月', '日'] for _ in ['和','差'] for i in range(12)],
    ['月生扶', '日生扶'],
    ["回头扶", "回头生", "回头克"],
    ['动爻扶', '动爻生', '动爻克'],
    ['化差11', '化差1', '化差3', '化差9'],  # 为下文做准备
    ['化进', '化退', '伏吟', '反吟'],
    # ['变差3', '变差9'],# 变差，动爻对全部爻的冲合
    # ['化明日','化月破']
    # 日月
]

'''这2个方法比较笨，储存起来太多了。需要用的时候再计算，然后缓存。
def update_from_tensor(tensor, operator):
    for i in range(2):
        mask = (tensor.yinyang == i + 1).astype(int)  # 阳=1，阴=2
        operator.update_dynamic_plane(9 + i, mask)
    for i in range(4):
        mask = (tensor.block == i).astype(int)  # 安静=0，发动=1，变卦=2，伏藏=3
        operator.update_dynamic_plane(11 + i, mask)
    for i in range(5):
        mask = (tensor.wx == i).astype(int)  #
        operator.update_dynamic_plane(15 + i, mask)
    for i in range(12):
        mask = (tensor.zhi == i).astype(int)  # 亥=0，子=1，
        operator.update_dynamic_plane(20 + i, mask)

# mapping是动态生成的，今后不再需要手动set_mapping，按需生产，并且缓存。

def set_mapping(gua_dict, operator):
    
    # 根据operator的set_instance_mappings方法，把高级的灵活多变的术语，转为低级的相对固定的术语。如五行、地支、爻位、主卦变卦伏藏本宫卦等。
    # 但是一口气添加太多了，不好，最好是惰性加载。
    
    sf, ot = gua_dict['selfIdx'], gua_dict['otherIdx']
    so_min = min(sf, ot)
    wx_gua = REMINDER_TO_WX[gua_dict['gua'] // 8]

    inter = '(' + '|'.join([i + '爻' for i in YAO_WEI[so_min + 1:so_min + 3]]) + ')'
    mapping = {
        "间爻": f"主卦&{inter}",
        "世": f"{YAO_WEI[sf]}爻",
        "应": f"{YAO_WEI[ot]}爻",
        "间": inter,
        "空亡": ZHI[gua_dict['empty']] + '|' + ZHI[(gua_dict['empty'] + 1) % 12],

    }
    for line in range(6):
        mapping[ANIMALS[(gua_dict['six_mode'] + 10 - line) % 6]] = YAO_WEI[line] + '爻'
    for lqin, val in enumerate(LQin):
        mapping[val] = WX[(lqin + wx_gua) % 5]

    for diff, val in enumerate(WXDiff):
        mapping['月' + val] = WX[(diff + ZHI_TO_WX[gua_dict['m']]) % 5]
        mapping['日' + val] = WX[(diff + ZHI_TO_WX[gua_dict['d']]) % 5]

    for i in range(12):
        mapping['月差' + str(i)] = ZHI[(i + gua_dict['m']) % 12]
        mapping['月和' + str(i)] = ZHI[(i - gua_dict['m']) % 12]
        mapping['日差' + str(i)] = ZHI[(i + gua_dict['d']) % 12]
        mapping['日和' + str(i)] = ZHI[(i - gua_dict['d']) % 12]

    for k, v in mapping.items():
        # print(k, '==>', v)
        operator.set_flexible_mappings(k, v)
'''




def example():
    gua_dict['yong_shen'] = '妻财'
    gua = AttrFuncDict(**gua_dict)
    tensor = DictTensor(gua)
    # print(tensor.yinyang)
    # print(tensor.mask)
    # print(tensor.gan)
    print(tensor.zhi)
    print(tensor.wx)
    print(tensor.wx_alter())
    print(tensor.wx_vary(2))
    print(tensor.zhi_alter())
    # print(tensor.block)

    lyp = LiuYaoPlace(gua)
    lyp.place(output=True)
    for s in clauses[6]:
        operator.print_info(s)

    print(operator.judge("回头耗"))
    # print(operator.judge("主卦&世&兄弟&(火|土)"))
    # print(operator.judge("世爻&!月生扶&兄弟&(火|土)"))
    # print(operator.judge("世爻&月不生扶&兄弟&(火|土)"))



if __name__ == '__main__':

    clause = '日合'
    # clause = '变卦'
    # clause = "变卦&化差9"
    # clause = '主卦&化进'
    # clause = '化进'# '回头扶' # '化差3|化差9'
    # clause = '化合'
    # clause = '化差8'
    operator = HexagramMatrixOperator(gua_dict)
    print('zhi',operator.dynamic_layer.tensor.zhi)  # 如有必要，查看原始张量
    LiuYaoPlace(operator.dynamic_layer.tensor.gua).place(output=True) # 如有必要，打印卦文
    operator.print_info(clause) # 如有必要，查看二进制矩阵
    # print(operator.judge(clause, is_plain))




